﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.FxCop.Sdk;

namespace SinacorRules
{
    [BaseAddIn.Rules.DoubleClass("Rule_EventHandlerSuffix")]
    public sealed class Rule_EventHandlerSuffix_FXCop : BaseAddIn.Rules.BaseRuleFXCop
    {
        #region Constructor

        public Rule_EventHandlerSuffix_FXCop()
            : base("EventHandlerSuffix", "SinacorRules.SinacorRules", typeof(Rule_EventHandlerSuffix_FXCop).Assembly)
        {
        }

        #endregion

        #region Public Override Methods

        public sealed override ProblemCollection Check(Member member)
        {
            Method metodo = null;

            if (member is Method)
            {
                metodo = (Method)member;

                if (metodo.Locals != null)
                {
                    foreach (Local local in metodo.Locals)
                    {
                        if (Analisavariavel(local))
                        {
                            AddError(local, "EventHandlerSuffixResolution", metodo.DeclaringType.Name.Name, local.Name.Name, metodo.DeclaringType.Namespace.Name);
                        }
                    }
                }
            }

            return base.Problems;
        }

        #endregion

        #region Private Methods

        private bool Analisavariavel(Local local)
        {
            bool retorno = false;
            DelegateNode delegateExaminar;
            Type tipo;
            Type tipoParametroObjeto;
            Type tipoParametroEventArgs;

            if (!local.Name.Name.Contains("$")
                && local.Type is DelegateNode)
            {
                delegateExaminar = (DelegateNode)local.Type;

                tipo = Type.GetType(local.Type.GetFullUnmangledNameWithoutTypeParameters());

                if (tipo == typeof(System.EventHandler)
                    || tipo.IsSubclassOf(typeof(System.EventHandler)))
                {
                    retorno = true;
                }
                else if (delegateExaminar.Parameters.Count == 2)
                {
                    tipoParametroObjeto = Type.GetType(delegateExaminar.Parameters[0].Type.GetFullUnmangledNameWithoutTypeParameters());
                    tipoParametroEventArgs = Type.GetType(delegateExaminar.Parameters[1].Type.GetFullUnmangledNameWithoutTypeParameters());

                    if (tipoParametroObjeto == typeof(System.Object)
                        || tipoParametroObjeto.IsSubclassOf(typeof(System.Object)))
                    {
                        if (tipoParametroEventArgs == typeof(System.EventArgs)
                           || tipoParametroEventArgs.IsSubclassOf(typeof(System.EventArgs)))
                        {
                            retorno = true;
                        }
                    }
                }
            }

            return retorno;
        }

        #endregion
    }
}
